using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Soyuz5.Utility
{
    /// <summary>
    /// Format string based on named paramaters
    /// </summary>
    public class FormatString
    {
        string _text = string.Empty;

        /// <summary>
        /// Current value (replaced values are applied)
        /// </summary>
        public string Text
        {
            get { return _text; }
            set { _text = value; }
        }
        
        /// <summary>
        /// Create a new format string ie new FormatString("{Hello} the day of week  is {MyDate:dddd}").Replace("Hello", "Hello World").Replace("MyDate", DateTime.Now);
        /// </summary>
        /// <param name="text"></param>
        public FormatString(string text)
        {
            _text = text;
        }

        /// <summary>
        /// Replace a holder with given value based on name
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public FormatString Replace(string key, object value)
        {
            string _reExpression = string.Format("\\{{{0}\\:?(?<format>\\b[^\\}}]*)[^\\}}]*\\}}", key);

            Regex regex = new Regex(
                  _reExpression,
                RegexOptions.IgnoreCase
                | RegexOptions.CultureInvariant
                | RegexOptions.IgnorePatternWhitespace
                | RegexOptions.Compiled
                );

            _text = regex.Replace(_text, new MatchEvaluator(delegate(Match m)
            {
                Group formatGroup = m.Groups["format"];

                if (formatGroup != null)
                {
                    string format = string.Format("{{0:{0}}}", formatGroup.Value);
                    return string.Format(format, value);
                }

                return string.Format("{0}", value);
            }));

            return this;
        }

        public override string ToString()
        {
            return _text;
        }
    }
}
